<?php

declare(strict_types=1);

namespace App\Service;

use EasyWeChat\Factory;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use Hyperf\Guzzle\CoroutineHandler;
use Hyperf\Guzzle\HandlerStackFactory;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Utils\ApplicationContext;
use Overtrue\Socialite\Providers\AbstractProvider;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\HttpFoundation\Request;

class WechatFactory
{
    /**
     * 公众号
     * @param bool $hasRequest
     * @return \EasyWeChat\OfficialAccount\Application
     */
    public function officialAccount($hasRequest = true)
    {
        $app = Factory::officialAccount(config('wechat.official_account.default'));

        $container = ApplicationContext::getContainer();

        $config = $app['config']->get('http', []);
        $config['handler'] = $container->get(HandlerStackFactory::class)->create();

        $app->rebind('http_client', new Client($config));
        $app['guzzle_handler'] = new CoroutineHandler(); // 重写 Handler
        $app['cache'] = $container->get(CacheInterface::class);

        if ($hasRequest) {
            $request = $container->get(RequestInterface::class);
            $request !== null && $app['request'] = new Request($request->getQueryParams(), $request->getParsedBody(), [], $request->getCookieParams(), [], $request->getServerParams(), $request->getBody()->getContents());
        }

        AbstractProvider::setGuzzleOptions([
            'http_errors' => false,
            'handler' => HandlerStack::create(new CoroutineHandler()),
        ]);

        return $app;
    }

    /**
     * 微信支付
     * @return \EasyWeChat\Payment\Application
     */
    public function payment()
    {
        $app = Factory::payment(config('wechat.payment.default'));

        $container = ApplicationContext::getContainer();

        $config = $app['config']->get('http', []);
        $config['handler'] = $container->get(HandlerStackFactory::class)->create();
        $app->rebind('http_client', new Client($config));

        $app['guzzle_handler'] = new CoroutineHandler(); // 重写 Handler
        $app['cache'] = $container->get(CacheInterface::class);

        AbstractProvider::setGuzzleOptions([
            'http_errors' => false,
            'handler' => HandlerStack::create(new CoroutineHandler()),
        ]);

        return $app;
    }
}
